#ifndef __CONTROLS_H
#define __CONTROLS_H

namespace math { namespace ui 
{

class ControlBase : public GLView 
{
public : 
	ControlBase (Model * model, unsigned ID) : GLView (model, ID) {}
	~ControlBase () {}

	// Add more function for painting the controls. 

	void beginWinCoords()
	{
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();
		glTranslatef(0.0f, (GLfloat)get_height() - 1, 0.0f);
		glScalef(1.0f, -1.0f, 1.0f);

		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		glOrtho(0, get_width(), 0, get_height(), -1, 1);

		glMatrixMode(GL_MODELVIEW);
	}
	void set_caption (const char * cap)
	{
		this->m_caption = cap; 
	}
	void set_caption (const std::string & str)
	{
		this->m_caption = str ;
	}
	void endWinCoords()
	{
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();

		glMatrixMode(GL_MODELVIEW);
		glPopMatrix();
	}


	virtual void paint () 
	{


	}
protected :
	std::string m_caption ;
};

class Button  : public ControlBase
{
public :
	Button (Model * model, unsigned ID) : ControlBase (model, ID) {}
//	Button (unsigned w, unsigned h, unsigned x = 0, unsigned y = 0)  {}
	
	typedef math::vector<float, 4> frgba_type ;

	
	virtual void paint() 
	{
		// scissor the region
		set_scissor(); 
		// Set the left view
		setViewport(this->m_xpos, this->m_ypos, this->m_width, this->m_height, mainView.projectionNear, mainView.projectionFar);
		//setOrthoViewport(this->m_xpos, this->m_ypos, this->m_width, this->m_height, mainView.projectionNear, mainView.projectionFar);

		glDisable(GL_LIGHTING);
		glTranslatef(mainView.focus.x, mainView.focus.y, mainView.focus.z);

		//glClearColor(0.0f, 0.0f, 0.0f, 1);
		color_type & c = this->mainView.backgroundColor  ;
		glClearColor(c.r, c.g, c.b, c.a);

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		//sence();
		glScalef(8.0f, 2.0f, 2.0f);
		
		frgba_type button_color (0, 0, 1.0, 1.0);

		if (m_mleftdown == true )
		{
			button_color = frgba_type(1.0, 0, 0, 1.0);
		}
		glDisable(GL_DEPTH_TEST); 
		glBegin(GL_QUADS);
		glColor4f (button_color.r, button_color.g, button_color.b, button_color.a);
		glVertex3f( -1.0f, 1.0f, 0.0f);              // Top
		glVertex3f(-1.0f,-1.0f, 0.0f);              // Bottom Left
//		glColor3f (0, 0, 0.0);
		glVertex4f( 1.0f,-1.0f, 0.0f, 1.0);              // Bottom Right
		glVertex3f( 1.0f,1.0f, 0.0f);              // Bottom Right
		glEnd();
		  
		glEnd();                            // Finished Drawing The Triangle
	}

};

class StateButton  : public ControlBase
{
public :
	StateButton (Model * model, unsigned ID) : ControlBase (model, ID), is_on(false) {}
//	Button (unsigned w, unsigned h, unsigned x = 0, unsigned y = 0)  {}
	
	typedef math::vector<float, 4> frgba_type ;

	void switch_state () 
	{
		is_on = ! is_on ;
	}
	bool get_state () const {return this->is_on ; }
	virtual void paint() 
	{
		// scissor the region
		set_scissor(); 
		// Set the left view
		setViewport(this->m_xpos, this->m_ypos, this->m_width, this->m_height, mainView.projectionNear, mainView.projectionFar);
		//setOrthoViewport(this->m_xpos, this->m_ypos, this->m_width, this->m_height, mainView.projectionNear, mainView.projectionFar);

		glDisable(GL_LIGHTING);
		glTranslatef(mainView.focus.x, mainView.focus.y, mainView.focus.z);

		//glClearColor(0.0f, 0.0f, 0.0f, 1);
		color_type & c = this->mainView.backgroundColor  ;
		glClearColor(c.r, c.g, c.b, c.a);

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		//sence();
		glScalef(8.0f, 2.0f, 2.0f);
		
		
		frgba_type button_color (0, 0, 1.0, 1.0);

		if (is_on == true )
		{
			button_color = frgba_type(1.0, 0, 0, 1.0);
		}
		glDisable(GL_DEPTH_TEST); 
		glBegin(GL_QUADS);
		glColor4f (button_color.r, button_color.g, button_color.b, button_color.a);
		glVertex3f( -1.0f, 1.0f, 0.0f);              // Top
		glVertex3f(-1.0f,-1.0f, 0.0f);              // Bottom Left
//		glColor3f (0, 0, 0.0);
		glVertex4f( 1.0f,-1.0f, 0.0f, 1.0);              // Bottom Right
		glVertex3f( 1.0f,1.0f, 0.0f);              // Bottom Right
		glEnd();
		  
		glEnd();                            // Finished Drawing The Triangle
	}
protected :
	bool is_on ; 

};

class Slider : public ControlBase
{
public:
	Slider (Model * model, unsigned ID):		right (1.0f), ControlBase(model, ID) {}
//	Slider (unsigned w, unsigned h, unsigned x = 0, unsigned y = 0)  {}
	
	float get_position ()
	{
		
		float pos = (this->right + 1.0f) / 2.0f ;
		if (pos < 0.0) return 0.0 ; 
		else if (pos > 1.0f) return 1.0 ;
		else return pos; 
	}
	typedef math::vector<float, 4> frgba_type ;
	virtual void paint() 
	{
		/*
		if (m_mleftdown == true)
		{
			std::cout<<m_mouse_pos<<std::endl;
		}
		*/
		// scissor the region
		set_scissor(); 
		// Set the left view
		setViewport(this->m_xpos, this->m_ypos, this->m_width, this->m_height, mainView.projectionNear, mainView.projectionFar);
		//setOrthoViewport(this->m_xpos, this->m_ypos, this->m_width, this->m_height, mainView.projectionNear, mainView.projectionFar);

		glDisable(GL_LIGHTING);
		glTranslatef(mainView.focus.x, mainView.focus.y, mainView.focus.z);

		//glClearColor(0.0f, 0.0f, 0.0f, 1);
		color_type & c = this->mainView.backgroundColor  ;
		glClearColor(c.r, c.g, c.b, c.a);

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		//sence();
		glScalef(8.0f, 2.0f, 2.0f);
		
		frgba_type button_color (0, 0, 1.0, 1.0);

		if (m_mleftdown == true )
		{
			button_color = frgba_type(1.0, 0, 0, 1.0);
		}
		glDisable(GL_DEPTH_TEST); 

		glBegin(GL_QUADS);
		glColor4f (button_color.r, button_color.g, button_color.b, button_color.a);
		glVertex3f( -1.0f, 1.0f, 0.0f);              // Top
		glVertex3f(-1.0f,-1.0f, 0.0f);              // Bottom Left
//		glColor3f (0, 0, 0.0);

		if (m_mleftdown )
		{
			if (m_mouse_pos.x >=30 && m_mouse_pos.x <=170 )
				right = (m_mouse_pos.x - 30.0 ) / 140.0 * 2.0f -1.0f; 
			else if (m_mouse_pos.x < 30) right = -1.0f; 
			else right = 1.0f;
		}
		
		glVertex4f( right,-1.0f, 0.0f, 1.0);              // Bottom Right
		glVertex3f( right,1.0f, 0.0f);              // Bottom Right
		glEnd();

		Font font ;
		font.print (-0.5, -0.5, this->m_caption);
	}
protected:

	float right ; 

};

class PictureBox : public GLView
{
};


}}
#endif
